<div id="virtual-tree">
    <div id="background-box"></div>
    <div id="show-box"></div>
</div>

<script>

function onResize(el, callback) {
    const objEl = document.createElement("object");
    objEl.type = "text/html";
    objEl.data = "about:blank";
    objEl.setAttribute("style", `
        display: block;
        position: absolute;
        top: 0;
        left: 0;
        height: 100%;
        width: 100%;
        overflow: hidden;
        opacity: 0;
        pointer-events: none;
        z-index: -1;
    `);
    objEl.onload = (evt) => {
        objEl.contentDocument.defaultView.addEventListener("resize", (ev) => callback(ev));
    };
    el.appendChild(objEl);
}

/** @type { HTMLDivElement } */ const virtualTree = document.querySelector("#virtual-tree");
/** @type { HTMLDivElement } */ const backgroundBox = virtualTree.querySelector("#background-box");
/** @type { HTMLDivElement } */ const showBox = virtualTree.querySelector("#show-box");

const itemHeight = 34;

const data = new Array(10000).fill(null).map((_, index) => index + 1);
backgroundBox.style.height = `${data.length * itemHeight}px`;

function refreshShowData() {
    const scrollTop = virtualTree.scrollTop;
    const scrollHeight = virtualTree.clientHeight;

    const showLength = Math.ceil(scrollHeight / itemHeight) + 1;

    const showFirstIndex = Math.floor(scrollTop / itemHeight);
    const showTop = showFirstIndex * itemHeight;

    const showData = data.slice(showFirstIndex, showFirstIndex + showLength);

    const listHTML = showData.map((index) => `<div>${index}</div>`).join("");
    showBox.style.transform = `translateY(${showTop}px)`;
    showBox.innerHTML = listHTML;
}

virtualTree.addEventListener("scroll", () => {
    refreshShowData();
});

onResize(virtualTree, () => {
    refreshShowData();
});

setTimeout(() => {
    refreshShowData();
});
</script>

<style>
#virtual-tree {
    height: 400px;
    overflow: auto;
    border: 1px solid #333;
    position: relative;
}
#virtual-tree > #show-box {
    position: absolute;
    top: 0;
    left: 0;
}

#virtual-tree > #show-box > * {
    height: 34px;
}
</style>